/*****************************************************************************
 *  ENTROPY - emerging network to reduce orwellian potency yield
 *
 *  Copyright (C) 2002 Juergen Buchmueller <pullmoll@stop1984.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software Foundation,
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 *	$Id: memalloc.h,v 1.4 2006/02/18 20:30:22 pullmoll Exp $
 *****************************************************************************/
#ifndef	_memalloc_h_
#define	_memalloc_h_

#include "osd.h"

/* define non-zero to use our own memory alloc implementation */
#ifndef	MEM_ALLOC_IMPL
#define	MEM_ALLOC_IMPL	0
#endif

#ifndef	MEM_DEBUG
#define	MEM_DEBUG 0
#endif

#undef	FILE_LINE_ARGS
#undef	FILE_LINE_PARMS
#if	MEM_DEBUG
#define	FILE_LINE_ARGS	, char *file, uint32_t line
#define	FILE_LINE_PARMS	, __FILE__, __LINE__
#define	AT_FILE_LINE at_file_line(file,line)
#else
#define	FILE_LINE_ARGS
#define	FILE_LINE_PARMS
#define	AT_FILE_LINE ""
#endif

#define	MEM_POOLSIZE	(16*4096)
#define	MEM_POOLSEGS	16

typedef struct mem_pool_s {
	size_t total;
	size_t alloc_len;
	size_t avail_len;
	void *allocated;
	void *available;
	size_t pool_cnt;				/* count of pools */
	size_t brk[MEM_POOLSEGS];		/* current brk per pool */
	size_t max[MEM_POOLSEGS];		/* max brk per pool */
	uint8_t *pool[MEM_POOLSEGS];	/* pool memory */
	uint8_t data[1];				/* for mmap(): flat mem */
}	mem_pool_t;

typedef struct mem_pool_stats_s {
	size_t total;					/* total amount of memory */
	size_t used;					/* used amount of memory */
	size_t free;					/* free amount of memory */
	size_t allocated;				/* number of nodes in the allocated list */
	size_t available;				/* number of nodes in the available list */
}	mem_pool_stats_t;

#ifdef	__cplusplus
extern "C" {
#endif
extern mem_pool_t *g_mem;

caddr_t mem_malloc(size_t size FILE_LINE_ARGS);
caddr_t mem_calloc(uint32_t num, size_t size FILE_LINE_ARGS);
caddr_t mem_realloc(caddr_t ptr, size_t size FILE_LINE_ARGS);
caddr_t mem_strdup(const char *src FILE_LINE_ARGS);
caddr_t mem_strndup(const char *src, size_t size FILE_LINE_ARGS);
void mem_free(caddr_t ptr FILE_LINE_ARGS);
int mem_valid(caddr_t ptr FILE_LINE_ARGS);
int mem_stats(mem_pool_stats_t *stats FILE_LINE_ARGS);

#define xmalloc(size) mem_malloc(size FILE_LINE_PARMS)
#define xcalloc(num,size) mem_calloc(num, size FILE_LINE_PARMS)
#define xrealloc(ptr,size) mem_realloc((caddr_t)ptr, size FILE_LINE_PARMS)
#define xstrdup(src) mem_strdup(src FILE_LINE_PARMS)
#define xstrndup(src,size) mem_strndup(src, size FILE_LINE_PARMS)
#define	xstrset(dst,src) mem_strset(&dst, src FILE_LINE_PARMS)
#define xfree(ptr) { mem_free((caddr_t)ptr FILE_LINE_PARMS); ptr = NULL; }
#define xcfree(ptr) { mem_free((caddr_t)ptr FILE_LINE_PARMS); ptr = NULL; }
#define xvalid(ptr) mem_valid((caddr_t)ptr FILE_LINE_PARMS)
#define	xstats(stats) mem_stats(stats FILE_LINE_PARMS)

void mem_pool_exit(void);
int mem_pool(void);

#ifdef	__cplusplus
}
#endif

#endif	/* _memalloc_h */
